//
//  FirstViewController.swift
//  MySpots
//
//  Created by Chen Dong on 2018/11/22.
//  Copyright © 2018 chen dong. All rights reserved.
//

import UIKit
import CoreLocation
import CoreData

class CurrentLocationViewController: UIViewController, CLLocationManagerDelegate {

    @IBOutlet weak var messageLabel: UILabel!
    @IBOutlet weak var latitudeLabel: UILabel!
    @IBOutlet weak var longitudeLabel: UILabel!
    @IBOutlet weak var addressLabel: UILabel!
    @IBOutlet weak var tagButton: UIButton!
    @IBOutlet weak var getButton: UIButton!
    
    @IBOutlet weak var containerView: UIView!
    var logoVisible = false
    
    lazy var logoButton: UIButton = {
        let button = UIButton(type: .custom)
        button.setBackgroundImage(UIImage(named: "Logo"), for: .normal)
        button.sizeToFit()
        button.addTarget(self, action: #selector(getLocation), for: .touchUpInside)
        button.center.x = self.view.bounds.midX
        button.center.y = 220
        return button
    }()
    
    func showLogoView() {
        if !logoVisible {
            logoVisible = true
            containerView.isHidden = true
            view.addSubview(logoButton)
        }
    }
    
    func hideLogoView() {
        logoVisible = false
        containerView.isHidden = false
        logoButton.removeFromSuperview()
    }
    
    let locationManager = CLLocationManager()
    var location: CLLocation?
    var updatingLocation = false
    var lastLocationError: Error?
    
    let geocoder = CLGeocoder() // 1. 添加geo解析器
    var placemark: CLPlacemark?
    var performingReverseGeocoding = false
    var lastGeocodingError: Error?
    
    var managedObjectContext: NSManagedObjectContext!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        updateUI()
        updateGetButton()
    }
    
    func updateGetButton() {
        let spinnerTag = 1000
        
        if updatingLocation {
            getButton.setTitle("停止定位", for: .normal)
            
            if view.viewWithTag(spinnerTag) == nil {
                let spinner = UIActivityIndicatorView(style: .gray)
                spinner.center = messageLabel.center
                spinner.center.y += spinner.bounds.size.height/2 + 15
                spinner.startAnimating()
                spinner.tag = spinnerTag
                containerView.addSubview(spinner)
            }
        } else {
            getButton.setTitle("我的位置", for: .normal)
            
            if let spinner = view.viewWithTag(spinnerTag) {
                spinner.removeFromSuperview()
            }
            
        }
//        if updatingLocation {
//            getButton.setTitle("停止定位", for: .normal)
//        } else {
//            getButton.setTitle("我的位置", for: .normal)
//        }
    }

    fileprivate func startLocationManager() {
        if CLLocationManager.locationServicesEnabled() {
            
            locationManager.delegate = self
            locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
            locationManager.startUpdatingLocation()
            updatingLocation = true
        }
    }
    
    @IBAction func getLocation(_ sender: Any) {
        let authStatu = CLLocationManager.authorizationStatus()
        if authStatu == .notDetermined {
            locationManager.requestWhenInUseAuthorization()
            return
        }
        if authStatu == .denied || authStatu == .restricted {
            let alert = UIAlertController(title: "定位服务已关闭", message: "请通过设置允许应用使用定位服务", preferredStyle: .alert)
            let action = UIAlertAction(title: "确定", style: .default) { _ in
                UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!, options: [:], completionHandler: nil)
            }
            alert.addAction(action)
            present(alert, animated: true, completion: nil)
        }
        
        if updatingLocation {
            stopLocationManager()
        } else {
            location = nil
            lastLocationError = nil
            if logoVisible {
                hideLogoView()
            }
            startLocationManager()
        }
        
        updateUI()
        updateGetButton()
    }
    
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        let newLocation = locations.last!
        print("UpdateLocation:\(newLocation)")
        
        if newLocation.timestamp.timeIntervalSinceNow < -5 {
            return
        }
        if newLocation.horizontalAccuracy < 0 {
            return
        }
        if location == nil || location!.horizontalAccuracy > newLocation.horizontalAccuracy {
            
            location = newLocation
            lastLocationError = nil
            updateUI()
            
            if newLocation.horizontalAccuracy <= locationManager.desiredAccuracy {
                stopLocationManager()
                updateGetButton()
            }
            
            if !performingReverseGeocoding {
                performingReverseGeocoding = true
                
                // 利用geo解析器进行反向地址解析
                geocoder.reverseGeocodeLocation(newLocation) { (placemarks, error) in
                    self.lastGeocodingError = error
                    if error == nil, let p = placemarks, !p.isEmpty {
                        self.placemark = p.last!
                    } else {
                        self.placemark = nil
                    }
                    
                    self.performingReverseGeocoding = false
                    self.updateUI()
                }
            }
        }
    }
    
    func updateUI() {
        if let location = location {
            latitudeLabel.text = String(format: "%.8f", location.coordinate.latitude)
            longitudeLabel.text = String(format: "%.8f", location.coordinate.longitude)
            tagButton.isHidden = false
            messageLabel.text = ""
            
            if let placemark = placemark {
                addressLabel.text = addressString(from: placemark)
            } else if performingReverseGeocoding {
                addressLabel.text = "正在搜索地址..."
            } else if lastGeocodingError != nil {
                addressLabel.text = "搜索地址出错"
            } else {
                addressLabel.text = "没有找到地址"
            }
        } else {
            latitudeLabel.text = ""
            longitudeLabel.text = ""
            addressLabel.text = ""
            tagButton.isHidden = true
            
            let statusMessage: String
            if let error = lastLocationError as NSError? {
                if error.domain == kCLErrorDomain && error.code == CLError.denied.rawValue {
                    statusMessage = "定位不可用"
                } else {
                    statusMessage = "定位服务出错"
                }
            } else if !CLLocationManager.locationServicesEnabled() {
                statusMessage = "定位不可用"
            } else if updatingLocation {
                statusMessage = "玩命定位中"
            } else {
               // statusMessage = "点击'我的位置'进行定位"
                statusMessage = ""
                showLogoView()
            }
            messageLabel.text = statusMessage
        }
    }
    
    func addressString(from placemark: CLPlacemark) -> String {
        var line1 = ""
        if let s = placemark.subThoroughfare {
            line1 += s + " "
        }
        if let s = placemark.thoroughfare {
            line1 += s
        }
        var line2 = ""
        if let s = placemark.locality {
            line2 += s + " "
        }
        if let s = placemark.administrativeArea {
            line2 += s + " "
        }
        if let s = placemark.postalCode {
            line2 += s
        }
        return line1 + "\n" + line2
    }
    
    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        print("FailWithError:\(error)")
        if (error as NSError).code == CLError.locationUnknown.rawValue {
            return
        }
        lastLocationError = error
        stopLocationManager()
        updateUI()
        updateGetButton()
    }
    
    func stopLocationManager() {
        if updatingLocation {
            locationManager.stopUpdatingLocation()
            locationManager.delegate = nil
            updatingLocation = false
        }
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "TagLocation" {
            let navigationController = segue.destination as! UINavigationController
            let controller = navigationController.topViewController as! LocationDetailsViewController
            
            controller.coordinate = location!.coordinate
            controller.placemark = placemark
            controller.managedObjectContext = managedObjectContext
        }
    }
    
}

